/*
 * ActorState.java
 *
 * Created on 30 October 2006, 20:43
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package digitrix.fightclub.game;

import javax.microedition.lcdui.Image;
    
/**
 *
 * @author Josh
 * More of a structure than a object
 */
public class ActorState {    
    
    public static final int KEY_FIRE_DOWN        = 100;
    public static final int KEY_FIRE_UP          = 200;
    public static final int KEY_FIRE_LEFT        = 300;
    public static final int KEY_FIRE_RIGHT       = 400;
    public static final int KEY_FIRE_ONLY        = 500; 
        
    private Actor _actor; 
    
    private int _stateID = 0; 
    
    private int _keySequence;           // key sequence that executes the state
    private long _holdTime;             // for moves that require the button to be held down (power ups etc)
    private int _timeForAnim;           // the total running time for the state/animation 
    
    private int[] _frameSequence;       // the animation sequence associated for the state
    private int[] _frameDamage;         // for states that are attacks; this has the damage that each frame can inflict on the opponent 
    private int[] _frameVelocity;       // for frames that force the user to move (i.e. some flying kick)
    private int[] _frameSpecialEffect;  // special effects associated to a specific frame
    
    // Image details
    private Image _frames;              // actual Image for the state animation 
    private int _frameHeight;           // height of the image
    private int _frameWidth;            // width of the image 
    
    private int _repeats = -1;          // how many time the state is repeated (-1 = always repeat)
    private int _currentFrame;          // the current frame of the animation associated to the state/time
    
    // actual private variables (not influenced by the outside world) 
    private long _currentStateTime;
    private long _frameTime; 
    private int _timePerFrame = -1;
    private int _repeated; 
    private boolean _moved = false; // control variable to ensure that frame velocity is only executed once per frame and not 
                                    // for the amount of time the state is in that frame.
    private boolean _addedSpecialEffect = false; // control variable to ensure that frame special effect addition is only ececuted
                                                 // once per frame and not for the amount of time the frame is displayed for. 
    
    
    /** Creates a new instance of ActorState */
    public ActorState( Actor actor ) {
        _actor = actor; 
    }    
    
    public void activateState(){
        _currentStateTime = 0;
        _frameTime = 0; 
        _currentFrame = 0; 
        _repeated = 0;   
        _moved = false; 
        _addedSpecialEffect = false;
        
        // update actor properties
        getActor().setImage( _frames, _frameWidth, _frameHeight );
        getActor().setCurrentState( this );
        getActor().setFrameSequence( _frameSequence ); 
        getActor().resetReferencePoint(); 
        // reset y position (to keep the actor on the floor)
        int newY = World.getInstance().getWorldFloor() + (getActor().getOrginalHeight() - _frameHeight);
        
        // reset x position (to keep the player consistant)                 
        getActor().setPosition( getActor().getX(), newY );                
        
        if( _timePerFrame < 0 )
            _timePerFrame = getTimePerFrame(); 
        
        System.out.println( "[INFO] ActorState.activateState(1); current state = " + getStateID() + " for player " + (!_actor.isFacingLeft() ? "LEFT" : "RIGHT") );
    }
    
    public void tick( long elapsedTime ){
        _currentStateTime += elapsedTime;
        _frameTime += elapsedTime;                 
        
        boolean stateCompleted = false;                                 
        
        // process frame movement        
        if( !_moved && getFrameVelocity() != null && getFrameVelocity()[getCurrentFrame()] > 0 ){
            if( getActor().isFacingLeft() ){
                //getActor().setVelocityX( -1*getFrameVelocity()[getCurrentFrame()] );
                getActor().forcedMove( -1*getFrameVelocity()[getCurrentFrame()], 0 );
            } else{                
                //getActor().setVelocityX( getFrameVelocity()[getCurrentFrame()] );
                getActor().forcedMove( getFrameVelocity()[getCurrentFrame()], 0 );
            }
            
            _moved = true; 
        }
        
        // process special effect
        int specialEffectType = getFrameSpecialEffect();        
        if( !_addedSpecialEffect && specialEffectType >= 0 ){            
            World.getInstance().addSpecialEffect( specialEffectType, getActor() );
            _addedSpecialEffect = true; 
            System.out.println( "adding special effect" );
        }
        
        // state over or frame change? 
        if( _frameTime > _timePerFrame ){
            _moved = false; 
            _addedSpecialEffect = false; 
            // move to next frame 
            if( ++_currentFrame >= getFrameSequence().length ){                
                
                if( getRepeats() != -1 && (getRepeats() == 0 || ++_repeated > getRepeats()) ){
                    stateCompleted = true; 
                    getActor().stateComplete( this ); 
                }
                else{
                    setCurrentFrame(0); 
                }
            }
            
            if( !stateCompleted ){
                // update frame
                getActor().setFrame( getCurrentFrame() );                                                                 
            }                                    
            
            _frameTime = 0;
        }                               
    }
    
    public int getDamage(){
        if( getFrameDamage() == null  || getCurrentFrame() >= getFrameDamage().length )
            return 0; 
        
        return getFrameDamage()[getCurrentFrame()]; 
    }     
    
    public int getFrameSpecialEffect(){
        if( getSpecialEffects() == null || getCurrentFrame() >= getSpecialEffects().length )
            return -1; 
         
        return getSpecialEffects()[getCurrentFrame()]; 
    }

    //<editor-fold defaultstate="collapsed" desc="Mutator">
    private int getTimePerFrame(){
        return getTimeForAnim() / getFrameSequence().length;
    }
    
    public int getStateID(){
        return _stateID; 
    }
    
    public void setStateID( int value ){
        _stateID = value; 
    }
    
    public Actor getActor() {
        return _actor;
    }

    public void setActor(Actor actor) {
        this._actor = actor;
    }

    public int getKeySequence() {
        return _keySequence;
    }

    public void setKeySequence(int keySequence) {
        this._keySequence = keySequence;
    }

    public long getHoldTime() {
        return _holdTime;
    }

    public void setHoldTime(long holdTime) {
        this._holdTime = holdTime;
    }

    public int getTimeForAnim() {
        return _timeForAnim;
    }

    public void setTimeForAnim(int timeForAnim) {
        this._timeForAnim = timeForAnim;
    }

    public int[] getFrameSequence() {
        return _frameSequence;
    }

    public void setFrameSequence(int[] frameSequence) {
        this._frameSequence = frameSequence;
    }

    public int[] getFrameDamage() {
        return _frameDamage;
    }

    public void setFrameDamage(int[] frameDamage) {
        this._frameDamage = frameDamage;
    }

    public int[] getFrameVelocity() {
        return _frameVelocity;
    }

    public void setFrameVelocity(int[] frameVelocity) {
        this._frameVelocity = frameVelocity;
    }

    public Image getFrames() {
        return _frames;
    }

    public void setFrames(Image frames) {
        this._frames = frames;
    }

    public int getFrameHeight() {
        return _frameHeight;
    }

    public void setFrameHeight(int frameHeight) {
        this._frameHeight = frameHeight;
    }

    public int getFrameWidth() {
        return _frameWidth;
    }

    public void setFrameWidth(int frameWidth) {
        this._frameWidth = frameWidth;
    }

    public int getRepeats() {
        return _repeats;
    }

    public void setRepeats(int repeats) {
        this._repeats = repeats;
    }

    public int getCurrentFrame() {
        return _currentFrame;
    }

    public void setCurrentFrame(int currentFrame) {
        this._currentFrame = currentFrame;
    }
    
    public int[] getSpecialEffects(){
        return _frameSpecialEffect; 
    }
    
    public void setSpecialEffects( int[] specialEffects ){
        _frameSpecialEffect = specialEffects; 
    }
    //</editor-fold>
    
}
